package all.com.jinyongqunxiax.component;

import android.content.Context;
import android.content.res.Resources;
import android.text.InputType;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;

import com.randy.fundation.DrawUtils;
import com.randy.fundation.JxAssert;
import com.randy.fundation.JxFunc;
import com.randy.fundation.Logger;
import com.yarolegovich.lovelydialog.LovelyChoiceDialog;

import java.util.ArrayList;
import java.util.List;

import all.com.jinyongqunxiax.R;
import all.com.jinyongqunxiax.view.GuideLineView;
import all.com.jinyongqunxiax.view.JxHud;
import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public class JxForm {
    private RecyclerView            recyclerView;
    private List<AbstractViewModel> viewModels = new ArrayList<>();

    public void add(AbstractViewModel viewModel) {
        viewModels.add(viewModel);
    }

    public void add(List<AbstractViewModel> viewModels) {
        this.viewModels.addAll(viewModels);
    }

    public void refresh() {
        if (recyclerView == null) {
            Logger.e("call connect(Context context, RecyclerView recyclerView) first");
            JxHud.alert("call connect(Context context, RecyclerView recyclerView) first");
            return;
        }

        RecyclerView.Adapter adapter = recyclerView.getAdapter();
        if (adapter != null) {
            adapter.notifyDataSetChanged();
        }
    }

    public void connect(Context context, RecyclerView recyclerView) {
        this.recyclerView = recyclerView;
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
        // not work recyclerView.setFocusableInTouchMode(true); // 滑动时 移除输入框焦点
        recyclerView.setAdapter(new RecyclerView.Adapter() {
            @Override
            public int getItemCount() {
                return viewModels.size();
            }

            @Override
            public int getItemViewType(int position) {
                AbstractViewModel viewModel = viewModels.get(position);
                return viewModel.viewResId;
            }

            @NonNull
            @Override
            public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                LayoutInflater inflater = LayoutInflater.from(parent.getContext());
                View           view     = inflater.inflate(viewType, parent, false);
                return new ViewHolder(view);
            }

            @Override
            public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
                ((ViewHolder) holder).bind(position);
            }
        });
    }

    public interface OnClickListener {
        /**
         * Called when a view has been clicked.
         *
         * @param viewModel 当前的数据模型
         * @param v         The view that was clicked.
         */
        void onClick(AbstractViewModel viewModel, View v);
    }

    public enum FieldAction {
        /**
         * 无动作
         */
        NONE,
        /**
         * 单项选择
         */
        SINGLE_PICK,
        /**
         * 多项选择
         */
        MULTI_PICK,
        /**
         * 多行文本
         */
        MULTI_LINE,

        /**
         * 单行文本
         */
        SINGLE_LINE,
        /**
         * 小数
         */
        DECIMAL,
        /**
         * 整数
         */
        INTEGER
    }

    public static class Picker {
        String       title;
        List<String> actions;
        boolean[]    selections;

        public static class Builder {
            private Picker value;

            public Picker value() {
                return value;
            }

            public static Builder build() {
                Builder builder = new Builder();
                builder.value = new Picker();
                return builder;
            }

            public Builder title(String title) {
                value.title = title;
                return this;
            }

            public Builder actions(List<String> actions) {
                value.actions = actions;
                return this;
            }

            public Builder selections(boolean[] selections) {
                value.selections = selections;
                return this;
            }
        }
    }

    public static class TextField {
        String label;
        String value;

        FieldAction labelAction = FieldAction.NONE;
        FieldAction valueAction = FieldAction.SINGLE_LINE;

        String hint;

        Picker labelPicker;
        Picker valuePicker;

        public static class Builder {
            private TextField value;

            public TextField value() {
                return value;
            }

            public static Builder build(String label, String value) {
                Builder builder = new Builder();
                builder.value = new TextField();
                builder.value.label = label;
                builder.value.value = value;
                return builder;
            }

            public static Builder build() {
                Builder builder = new Builder();
                builder.value = new TextField();
                return builder;
            }

            public Builder label(String action) {
                value.label = action;
                return this;
            }

            public Builder value(String action) {
                value.value = action;
                return this;
            }


            public Builder labelAction(FieldAction action) {
                value.labelAction = action;
                return this;
            }

            public Builder valueAction(FieldAction action) {
                value.valueAction = action;
                return this;
            }


            public Builder labelPicker(Picker picker) {
                value.labelPicker = picker;
                return this;
            }

            public Builder valuePicker(Picker picker) {
                value.valuePicker = picker;
                return this;
            }

            public Builder hint(String hint) {
                value.hint = hint;
                return this;
            }
        }
    }

    public static abstract class AbstractViewModel {
        int viewResId;
        int indentLevel;

        AbstractViewModel(@LayoutRes int viewResId, int indentLevel) {
            this.viewResId = viewResId;
            this.indentLevel = indentLevel;
        }

        /**
         * 进行资源绑定,
         *
         * @param view item view
         * @implNote ItemViewModel子类不要绑定删除按钮的事件
         * @implNote HeaderViewModel子类不要绑定添加按钮的事件
         */
        abstract void bind(View view);

        void afterBind(View view) {
            View indentView = view.findViewById(intentViewID());
            JxFunc.of(indentView).ifPresent(new JxFunc.Action<View>() {
                @Override
                public void yield(@NonNull View view) {
                    view.getLayoutParams().width = Math.round((indentLevel * GuideLineView.STEP + 1) * DrawUtils.density());
                }
            });


        }


        abstract @IdRes
        int intentViewID();


        void bindLabel(Context context, TextView textView, TextField field) {
            switch (field.labelAction) {
                case SINGLE_PICK:
                    textView.setOnClickListener(v -> showTitleSinglePicker(context, field));
                    break;
                case MULTI_PICK:
                    textView.setOnClickListener(v -> showTitleMultiPicker(context, field));
                    break;
                case NONE:
                    break;
                default:
                    JxAssert.failed(String.format("unsupported action %s", field.labelAction.toString()));
                    break;
            }
        }

        void bindValue(Context context, EditText editText, TextField field) {
            switch (field.valueAction) {
                case SINGLE_PICK:
                    editText.setFocusableInTouchMode(false);
                    editText.setOnClickListener(v -> showValueSinglePicker(context, field));
                    break;
                case MULTI_PICK:
                    editText.setFocusableInTouchMode(false);
                    editText.setOnClickListener(v -> showValueMultiPicker(context, field));
                    break;
                case DECIMAL:
                    editText.setRawInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
                    break;
                case INTEGER:
                    editText.setRawInputType(InputType.TYPE_NUMBER_FLAG_SIGNED | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
                    break;
                case SINGLE_LINE:
                    editText.setInputType(InputType.TYPE_CLASS_TEXT);
                    editText.setMaxLines(1);
                    break;
                case MULTI_LINE:
                    editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE);
                    editText.setMaxLines(10);
                    editText.setGravity(Gravity.START);
                    break;
                default:
                    JxAssert.failed(String.format("unsupported action %s", field.labelAction.toString()));
                    break;
            }

            //            editText.setFilters(new InputFilter[]{(source, start, end, dest, dstart, dend) -> {
            //                if (source.equals(".") && dest.toString().length() == 0) {
            //                    return "0.";
            //                }
            //                if (".".contains(dest.toString())) {
            //                    int index   = dest.toString().indexOf(".");
            //                    int length = dest.toString().substring(index).length();
            //                    if (length == 3) {
            //                        return "";
            //                    }
            //                }
            //                return null;
            //            }});
        }

        void showTitleSinglePicker(Context context, TextField field) {
            new LovelyChoiceDialog(context)
                    .setTopColorRes(R.color.colorGuildLine)
                    .setTitle(field.labelPicker.title)
                    .setItems(field.labelPicker.actions, (position, item) -> {
                    }).show();
        }

        void showTitleMultiPicker(Context context, TextField field) {
            new LovelyChoiceDialog(context)
                    .setTopColorRes(R.color.colorGuildLine)
                    .setTitle(field.labelPicker.title)
                    .setItemsMultiChoice(field.labelPicker.actions, field.labelPicker.selections, (positions, items) -> {

                    }).setConfirmButtonText("").show();
        }

        void showValueSinglePicker(Context context, TextField field) {
            new LovelyChoiceDialog(context)
                    .setTopColorRes(R.color.colorGuildLine)
                    .setTitle(field.valuePicker.title)
                    .setItems(field.valuePicker.actions, (position, item) -> {
                    }).show();
        }

        void showValueMultiPicker(Context context, TextField field) {
            new LovelyChoiceDialog(context)
                    .setTopColorRes(R.color.colorGuildLine)
                    .setTitle(field.valuePicker.title)
                    .setItemsMultiChoice(field.valuePicker.actions, field.valuePicker.selections, (positions, items) -> {

                    }).setConfirmButtonText("").show();
        }
    }

    static abstract class AbstractHeaderViewModel extends AbstractViewModel {
        OnClickListener addButtonListener;

        AbstractHeaderViewModel(int viewResId, int indentLevel, OnClickListener addButtonListener) {
            super(viewResId, indentLevel);
            this.addButtonListener = addButtonListener;
        }

        @Override
        void afterBind(View view) {
            super.afterBind(view);
            View button = view.findViewById(addButtonID());
            if (button != null) {
                button.setVisibility(addButtonListener != null ? View.VISIBLE : View.GONE);
                button.setOnClickListener(v -> {
                    if (addButtonListener != null) {
                        addButtonListener.onClick(AbstractHeaderViewModel.this, v);
                    }
                });
            }
            Context   context   = view.getContext();
            Resources resources = context.getResources();
            int       color;
            // 根据等级设置背景色
            switch (indentLevel) {
                case 0:
                    color = R.color.jx_form_header_background_level1;
                    break;
                case 1:
                    color = R.color.jx_form_header_background_level2;
                    break;
                case 2:
                    color = R.color.jx_form_header_background_level3;
                    break;
                case 3:
                    color = R.color.jx_form_header_background_level4;
                    break;
                case 4:
                    color = R.color.jx_form_header_background_level5;
                    break;
                case 5:
                    color = R.color.jx_form_header_background_level6;
                    break;
                default:
                    color = R.color.jx_form_header_background_level6;
                    break;
            }
            view.setBackgroundColor(resources.getColor(color));
        }

        /**
         * 提供添加按钮的ID, 方便控制按钮的显示与否
         *
         * @return 删除按钮的ID
         */
        abstract @IdRes
        int addButtonID();


    }

    static abstract class AbstractItemViewModel extends AbstractViewModel {
        OnClickListener removeButtonListener;

        AbstractItemViewModel(int viewResId, int indentLevel, OnClickListener removeButtonListener) {
            super(viewResId, indentLevel);
            this.removeButtonListener = removeButtonListener;
        }

        @Override
        void afterBind(View view) {
            super.afterBind(view);
            View button = view.findViewById(removeButtonID());
            if (button != null) {
                button.setVisibility(removeButtonListener != null ? View.VISIBLE : View.GONE);
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (removeButtonListener != null) {
                            removeButtonListener.onClick(AbstractItemViewModel.this, v);
                        }
                    }
                });
            }


        }

        /**
         * 提供删除按钮的ID, 方便控制按钮的显示与否
         *
         * @return 删除按钮的ID
         */
        abstract @IdRes
        int removeButtonID();
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        ViewHolder(@NonNull View itemView) {
            super(itemView);
        }

        void bind(int position) {
            AbstractViewModel viewModel = viewModels.get(position);
            viewModel.bind(this.itemView);
            viewModel.afterBind(this.itemView);
        }
    }
}
